package com.qingcheng.service.impl;
import com.alibaba.dubbo.config.annotation.Service;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.qingcheng.dao.AdMapper;
import com.qingcheng.entity.PageResult;
import com.qingcheng.pojo.business.Ad;
import com.qingcheng.service.business.AdService;
import com.qingcheng.util.CacheEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import tk.mybatis.mapper.entity.Example;

import java.util.Date;
import java.util.List;
import java.util.Map;

@Service
public class AdServiceImpl implements AdService {

    @Autowired
    private AdMapper adMapper;


    @Autowired
    private RedisTemplate redisTemplate;
    /**
     * 返回全部记录
     * @return
     */
    public List<Ad> findAll() {
        return adMapper.selectAll();
    }

    /**
     * 分页查询
     * @param page 页码
     * @param size 每页记录数
     * @return 分页结果
     */
    public PageResult<Ad> findPage(int page, int size) {
        PageHelper.startPage(page,size);
        Page<Ad> ads = (Page<Ad>) adMapper.selectAll();
        return new PageResult<Ad>(ads.getTotal(),ads.getResult());
    }

    /**
     * 条件查询
     * @param searchMap 查询条件
     * @return
     */
    public List<Ad> findList(Map<String, Object> searchMap) {
        Example example = createExample(searchMap);
        return adMapper.selectByExample(example);
    }

    /**
     * 分页+条件查询
     * @param searchMap
     * @param page
     * @param size
     * @return
     */
    public PageResult<Ad> findPage(Map<String, Object> searchMap, int page, int size) {
        PageHelper.startPage(page,size);
        Example example = createExample(searchMap);
        Page<Ad> ads = (Page<Ad>) adMapper.selectByExample(example);
        return new PageResult<Ad>(ads.getTotal(),ads.getResult());
    }

    /**
     * 根据Id查询
     * @param id
     * @return
     */
    public Ad findById(Integer id) {
        return adMapper.selectByPrimaryKey(id);
    }

    /**
     * 新增
     * @param ad
     */
    public void add(Ad ad) {
        adMapper.insert(ad);
        //更新此时的redis缓存
        //获取新增ad的position值
        String position = ad.getPosition();
        //从redis中获取key为option的值
        List<Ad> adList =(List<Ad>)redisTemplate.boundHashOps(CacheEnum.AD).get(position);
        //将新增的元素加入到redis中对应的集合中
        adList.add(ad);
        redisTemplate.boundHashOps(CacheEnum.AD).put(position,adList);

        //将数据库总查询所有option的值
       /* Example example=new Example(Ad.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("position",position);
        List<Ad> ads = adMapper.selectByExample(example);
        //将数据存入redis，覆盖原有数据
        redisTemplate.boundHashOps(CacheEnum.AD).put(position,ads);
*/
    }

    /**
     * 修改
     * @param ad
     */
    public void update(Ad ad) {
        //获取未修改的position值
        String position = adMapper.selectByPrimaryKey(ad.getId()).getPosition();
        //将修改的值存入数据库
        adMapper.updateByPrimaryKeySelective(ad);
        //判断原有位置是否改变
        if(!position.equals(ad.getPosition())){
            //跟新数据库
            saveAdsToRedis();
        }

    }

    /**
     *  删除
     * @param id
     */
    public void delete(Integer id) {
        Ad ad = adMapper.selectByPrimaryKey(id);
        //获取redis中的集合
        List<Ad> adList = (List<Ad>) redisTemplate.boundHashOps(CacheEnum.AD).get(ad.getPosition());
        adList.remove(ad);
        redisTemplate.boundHashOps(CacheEnum.AD).put(ad.getPosition(),adList);
        adMapper.deleteByPrimaryKey(id);
        //获取数据库中的ad

    }

    /**
     * 根据时间查询能首页广告
     * @return
     */
    @Override
    public List<Ad> findAds() {
        Example example=new Example(Ad.class);
        Example.Criteria criteria = example.createCriteria();
        //查询在主页位置显示
        criteria.andEqualTo("position","web_index_lb");
        //查询时间在star和end之间
        criteria.andLessThanOrEqualTo("startTime",new Date());
        criteria.andGreaterThanOrEqualTo("endTime",new Date());
        //根据status状态为1
        criteria.andEqualTo("status","1");
        //查询所有符合条件的Ad，并按照顺序排列
        return adMapper.selectByExample(example);
    }

    /**
     * 定义查询所有广告的方法
     */
    @Override
    public void saveAdsToRedis() {
        //将广告按照position为key存入redis中
        //获取广告按照position的所有分类
        List<String> positionList = adMapper.findAllPosition();
        //遍历所有集合，以position分类为条件查询到集合
        if(positionList.size()!=0){
            for (String position : positionList) {
                //将list集合以Hash值存入redis中，每个hash的key是position值
                Example example=new Example(Ad.class);
                Example.Criteria criteria = example.createCriteria();
                criteria.andEqualTo("status",1);
                criteria.andGreaterThanOrEqualTo("endTime",new Date());
                criteria.andLessThanOrEqualTo("startTime",new Date());
                criteria.andEqualTo("position",position);
                List<Ad> ads = adMapper.selectByExample(example);
                //将数据存入redis中
                redisTemplate.boundHashOps(CacheEnum.AD).put(position,ads);
            }
        }
    }

    /**
     * 定义根据广告位置在redis中取出数据
     * @param position
     * @return
     */
    @Override
    public List<Ad> getAdsFromRedis(String position) {
        return (List<Ad>) redisTemplate.boundHashOps(CacheEnum.AD).get(position);
    }

    /**
     * 构建查询条件
     * @param searchMap
     * @return
     */
    private Example createExample(Map<String, Object> searchMap){
        Example example=new Example(Ad.class);
        Example.Criteria criteria = example.createCriteria();
        if(searchMap!=null){
            // 广告名称
            if(searchMap.get("name")!=null && !"".equals(searchMap.get("name"))){
                criteria.andLike("name","%"+searchMap.get("name")+"%");
            }
            // 广告位置
            if(searchMap.get("position")!=null && !"".equals(searchMap.get("position"))){
                criteria.andLike("position","%"+searchMap.get("position")+"%");
            }
            // 状态
            if(searchMap.get("status")!=null && !"".equals(searchMap.get("status"))){
                criteria.andLike("status","%"+searchMap.get("status")+"%");
            }
            // 图片地址
            if(searchMap.get("image")!=null && !"".equals(searchMap.get("image"))){
                criteria.andLike("image","%"+searchMap.get("image")+"%");
            }
            // URL
            if(searchMap.get("url")!=null && !"".equals(searchMap.get("url"))){
                criteria.andLike("url","%"+searchMap.get("url")+"%");
            }
            // 备注
            if(searchMap.get("remarks")!=null && !"".equals(searchMap.get("remarks"))){
                criteria.andLike("remarks","%"+searchMap.get("remarks")+"%");
            }

            // ID
            if(searchMap.get("id")!=null ){
                criteria.andEqualTo("id",searchMap.get("id"));
            }

        }
        return example;
    }

}
